home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / df.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  5KB  |  217 lines

  1. /* df - disk free block printout    Author: Andy Tanenbaum */
  2.  
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <limits.h>
  6. #include <fcntl.h>
  7. #include <errno.h>
  8. #include <unistd.h>
  9. #include <stdio.h>
  10.  
  11. #include <minix/config.h>
  12. #include <minix/const.h>
  13. #include <minix/type.h>
  14. #include "../fs/const.h"
  15. #include "../fs/type.h"
  16. #include "../fs/super.h"
  17.  
  18. #define block_nr long        /* Allow big devices even if FS doesn't */
  19.  
  20. extern int errno;
  21. long bit_count();
  22. char *mtab = "/etc/mtab";
  23.  
  24. #define REPORT 0
  25. #define SILENT 1
  26.  
  27.  
  28. main(argc, argv)
  29. int argc;
  30. char *argv[];
  31. {
  32.   register int i;
  33.  
  34.   sync();            /* have to make sure disk is up-to-date */
  35.   fprintf(stdout, "\nDevice     Inodes  Inodes  Inodes       Blocks  Blocks  Blocks    ");
  36.   if (argc == 1)
  37.     fprintf(stdout, "Mounted on\n");
  38.   else
  39.     fprintf(stdout, "\n");
  40.  
  41.   fprintf(stdout, "           total   used    free         total   used    free\n");
  42.   fprintf(stdout, "           -----   -----   -----        -----   -----   -----\n");
  43.  
  44.   if (argc == 1) defaults();
  45.  
  46.   for (i = 1; i < argc; i++) df(argv[i], "", SILENT);
  47.   exit(0);
  48. }
  49.  
  50.  
  51. #define percent(num, tot)  ((int) ((100L * (num) + ((tot) - 1)) / (tot)))
  52.  
  53. df(name, mnton, silent)
  54. char *name, *mnton;
  55. int silent;
  56. {
  57.   register int fd;
  58.   ino_t i_count;
  59.   long z_count;
  60.   block_nr totblocks, busyblocks;
  61.   int i, j;
  62.   char buf[BLOCK_SIZE], *s0;
  63.   struct super_block super, *sp;
  64.  
  65.   if ((fd = open(name, O_RDONLY)) < 0) {
  66.     if (!silent) {
  67.         int e = errno;
  68.  
  69.         fprintf(stderr, "df: ");
  70.         errno = e;
  71.         perror(name);
  72.     }
  73.     return;
  74.   }
  75.   lseek(fd, (long) BLOCK_SIZE, SEEK_SET);    /* skip boot block */
  76.   if (read(fd, (char *) &super, SUPER_SIZE) != (int) SUPER_SIZE) {
  77.     fprintf(stderr, "df: Can't read super block of %s\n", name);
  78.     close(fd);
  79.     return;
  80.   }
  81.   lseek(fd, (long) BLOCK_SIZE * 2L, SEEK_SET);    /* skip rest of super block */
  82.   sp = &super;
  83.   if (sp->s_magic != SUPER_MAGIC) {
  84.     fprintf(stderr, "df: %s: Not a valid file system\n", name);
  85.     close(fd);
  86.     return;
  87.   }
  88.   i_count = (ino_t) bit_count(sp->s_imap_blocks, sp->s_ninodes + 1, fd);
  89.   if (i_count == -1) {
  90.     fprintf(stderr, "df: Can't find bit maps of %s\n", name);
  91.     close(fd);
  92.     return;
  93.   }
  94.   i_count--;            /* There is no inode 0. */
  95.  
  96.   z_count = bit_count(sp->s_zmap_blocks, sp->s_nzones, fd);
  97.   if (z_count == -1) {
  98.     fprintf(stderr, "df: Can't find bit maps of %s\n", name);
  99.     close(fd);
  100.     return;
  101.   }
  102.   totblocks = (block_nr) sp->s_nzones << sp->s_log_zone_size;
  103.   busyblocks = (block_nr) z_count << sp->s_log_zone_size;
  104.  
  105.   /* Print results. */
  106.   fprintf(stdout, "%s", name);
  107.   j = 10 - strlen(name);
  108.   while (j > 0) {
  109.     fprintf(stdout, " ");
  110.     j--;
  111.   }
  112.  
  113.   fprintf(stdout, " %5u   %5u   %5u      %7ld %7ld %7ld     %s\n",
  114.     sp->s_ninodes,        /* total inodes */
  115.     i_count,        /* inodes used */
  116.     sp->s_ninodes - i_count,/* inodes free */
  117.  
  118.     totblocks,        /* total blocks */
  119.     busyblocks,        /* blocks used */
  120.     totblocks - busyblocks,    /* blocsk free */
  121.  
  122.     strcmp(mnton, "device") == 0 ? "(root dev)" : mnton
  123.  
  124.     );
  125.   close(fd);
  126. }
  127.  
  128. long bit_count(blocks, bits, fd)
  129. unsigned blocks;
  130. unsigned bits;
  131. int fd;
  132. {
  133.   register char *wptr;
  134.   register int i;
  135.   register int b;
  136.   register unsigned busy;    /* bits fits in unsigned, so busy does too */
  137.   register char *wlim;
  138.   register int j;
  139.   static char buf[BLOCK_SIZE];
  140.   static unsigned bits_in_char[1 << CHAR_BIT];
  141.  
  142.   /* Precalculate bitcount for each char. */
  143.   if (bits_in_char[1] != 1) {
  144.     for (b = (1 << 0); b < (1 << CHAR_BIT); b <<= 1)
  145.         for (i = 0; i < (1 << CHAR_BIT); i++)
  146.             if (i & b) bits_in_char[i]++;
  147.   }
  148.  
  149.   /* Loop on blocks, reading one at a time and counting bits. */
  150.   busy = 0;
  151.   for (i = 0; i < blocks && bits != 0; i++) {
  152.     if (read(fd, buf, BLOCK_SIZE) != BLOCK_SIZE) return(-1);
  153.  
  154.     wptr = &buf[0];
  155.     if (bits >= CHAR_BIT * BLOCK_SIZE) {
  156.         wlim = &buf[BLOCK_SIZE];
  157.         bits -= CHAR_BIT * BLOCK_SIZE;
  158.     } else {
  159.         b = bits / CHAR_BIT;    /* whole chars in map */
  160.         wlim = &buf[b];
  161.         bits -= b * CHAR_BIT;    /* bits in last char, if any */
  162.         b = *wlim & ((1 << bits) - 1);    /* bit pattern from last ch */
  163.         busy += bits_in_char[b];
  164.         bits = 0;
  165.     }
  166.  
  167.     /* Loop on the chars of a block. */
  168.     while (wptr != wlim)
  169.         busy += bits_in_char[*wptr++ & ((1 << CHAR_BIT) - 1)];
  170.   }
  171.   return(busy);
  172. }
  173.  
  174.  
  175. char mtabbuf[1024];
  176. int mtabcnt;
  177.  
  178. getname(d, m)
  179. char **d, **m;
  180. {
  181.   int c;
  182.   static char *mp = mtabbuf;
  183.  
  184.   *d = mp;
  185.   *m = "";
  186.  
  187.   do {
  188.     if (--mtabcnt < 0) exit(0);
  189.     c = *mp++;
  190.     if (c == ' ') {
  191.         mp[-1] = 0;
  192.         *m = mp;
  193.     }
  194.   } while (c != '\n');
  195.   mp[-1] = 0;
  196. }
  197.  
  198.     defaults()
  199. {
  200. /* Use the root file system and all mounted file systems. */
  201.  
  202.   char *dev, *dir;
  203.  
  204.   close(0);
  205.   if (open(mtab, O_RDONLY) < 0 || (mtabcnt = read(0, mtabbuf, sizeof(mtabbuf))) <= 0) {
  206.     fprintf(stderr, "df: cannot read %s\n", mtab);
  207.     exit(1);
  208.   }
  209.  
  210.   /* Read /etc/mtab and iterate on the lines. */
  211.   while (1) {
  212.     getname(&dev, &dir);    /* getname exits upon hitting EOF */
  213.     df(dev, dir, REPORT);
  214.   }
  215.  
  216. }
  217.